package com.ycuwq.datepicker.date;

import com.ycuwq.datepicker.ResourceTable;
import com.ycuwq.datepicker.util.AttrUtils;
import com.ycuwq.datepicker.util.Utils;
import ohos.agp.components.AttrSet;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.element.Element;
import ohos.agp.utils.Color;
import ohos.app.Context;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;

/**
 * 日期选择器
 * Created by ycuwq on 2018/1/1.
 */
@SuppressWarnings("unused")
public class DatePicker extends DirectionalLayout implements YearPicker.OnYearSelectedListener,
        MonthPicker.OnMonthSelectedListener, DayPicker.OnDaySelectedListener {
    /**
     * * The constant DatePicker_itemTextSize
     */
    public static final String DATEPICKER_ITEMTEXTSIZE = "itemTextSize";
    /**
     * * The constant DatePicker_halfVisibleItemCount
     */
    public static final String DATEPICKER_HALFVISIBLEITEMCOUNT = "halfVisibleItemCount";
    /**
     * * The constant DatePicker_itemTextColor
     */
    public static final String DATEPICKER_ITEMTEXTCOLOR = "itemTextColor";
    /**
     * * The constant DatePicker_textGradual
     */
    public static final String DATEPICKER_TEXTGRADUAL = "textGradual";
    /**
     * * The constant DatePicker_selectedTextColor
     */
    public static final String DATEPICKER_SELECTEDTEXTCOLOR = "selectedTextColor";
    /**
     * * The constant DatePicker_selectedTextSize
     */
    public static final String DATEPICKER_SELECTEDTEXTSIZE = "selectedTextSize";
    /**
     * * The constant DatePicker_itemWidthSpace
     */
    public static final String DATEPICKER_ITEMWIDTHSPACE = "itemWidthSpace";
    /**
     * * The constant DatePicker_itemHeightSpace
     */
    public static final String DATEPICKER_ITEMHEIGHTSPACE = "itemHeightSpace";
    /**
     * * The constant DatePicker_zoomInSelectedItem
     */
    public static final String DATEPICKER_ZOOMINSELECTEDITEM = "zoomInSelectedItem";
    /**
     * * The constant DatePicker_wheelCyclic
     */
    public static final String DATEPICKER_WHEELCYCLIC = "wheelCyclic";
    /**
     * * The constant DatePicker_wheelCurtain
     */
    public static final String DATEPICKER_WHEELCURTAIN = "wheelCurtain";
    /**
     * * The constant DatePicker_wheelCurtainColor
     */
    public static final String DATEPICKER_WHEELCURTAINCOLOR = "wheelCurtainColor";
    /**
     * * The constant DatePicker_wheelCurtainBorder
     */
    public static final String DATEPICKER_WHEELCURTAINBORDER = "wheelCurtainBorder";
    /**
     * * The constant DatePicker_wheelCurtainBorderColor
     */
    public static final String DATEPICKER_WHEELCURTAINBORDERCOLOR = "wheelCurtainBorderColor";
    /**
     * * The constant WheelItemTextSize
     */
    public static int WheelItemTextSize = 16;
    /**
     * * The constant com_ycuwq_datepicker_selectedTextColor
     */
    public static int com_ycuwq_datepicker_selectedTextColor = 0xff33aaff;
    /**
     * * The constant WheelSelectedItemTextSize
     */
    public static int WheelSelectedItemTextSize = 20;
    /**
     * * The constant WheelItemWidthSpace
     */
    public static int WheelItemWidthSpace = 32;
    /**
     * * The constant WheelItemHeightSpace
     */
    public static int WheelItemHeightSpace = 16;
    /**
     * * The constant com_ycuwq_datepicker_divider
     */
    public static int com_ycuwq_datepicker_divider = 0xffcccccc;
    /**
     * The constant M year picker
     */
    private YearPicker mYearPicker;
    /**
     * The constant M month picker
     */
    private MonthPicker mMonthPicker;
    /**
     * The constant M day picker
     */
    private DayPicker mDayPicker;
    /**
     * The constant M max date
     */
    private Long mMaxDate;
    /**
     * The constant M min date
     */
    private Long mMinDate;
    /**
     * The constant M on date selected listener
     */
    private OnDateSelectedListener mOnDateSelectedListener;

    /**
     * Instantiates a new Date picker.
     *
     * @param context the context
     */
    public DatePicker(Context context) {
        this(context, null);
    }

    /**
     * Instantiates a new Date picker.
     *
     * @param context the context
     * @param attrs   the attrs
     */
    public DatePicker(Context context, AttrSet attrs) {
        this(context, attrs, null);
    }

    /**
     * Instantiates a new Date picker.
     *
     * @param context      the context
     * @param attrs        the attrs
     * @param defStyleAttr the def style attr
     */
    public DatePicker(Context context, AttrSet attrs, String defStyleAttr) {
        super(context, attrs, defStyleAttr);
        LayoutScatter.getInstance(getContext()).parse(ResourceTable.Layout_layout_date, this, true);
        initChild();
        initAttrs(context, attrs);
        mYearPicker.setBackground(getBackgroundElement());
        mMonthPicker.setBackground(getBackgroundElement());
        mDayPicker.setBackground(getBackgroundElement());
    }

    /**
     * Init attrs *
     *
     * @param context context
     * @param attrs   attrs
     */
    private void initAttrs(Context context, AttrSet attrs) {
        if (attrs == null) {
            return;
        }

        int textSize = AttrUtils.getDimensionFromAttr(attrs, DATEPICKER_ITEMTEXTSIZE,
                Utils.dp2px(context, WheelItemTextSize));
        int textColor = AttrUtils.getColorFromAttr(attrs, DATEPICKER_ITEMTEXTCOLOR,
                Color.BLACK.getValue());
        boolean isTextGradual = AttrUtils.getBooleanFromAttr(attrs, DATEPICKER_TEXTGRADUAL, true);
        boolean isCyclic = AttrUtils.getBooleanFromAttr(attrs, DATEPICKER_WHEELCYCLIC, false);
        int halfVisibleItemCount = AttrUtils.getIntFromAttr(attrs, DATEPICKER_HALFVISIBLEITEMCOUNT, 2);
        int selectedItemTextColor = AttrUtils.getColorFromAttr(attrs, DATEPICKER_SELECTEDTEXTCOLOR,
                com_ycuwq_datepicker_selectedTextColor);
        int selectedItemTextSize = AttrUtils.getDimensionFromAttr(attrs, DATEPICKER_SELECTEDTEXTSIZE,
                Utils.dp2px(context, WheelSelectedItemTextSize));
        int itemWidthSpace = AttrUtils.getDimensionFromAttr(attrs, DATEPICKER_ITEMWIDTHSPACE,
                Utils.dp2px(context, WheelItemWidthSpace));
        int itemHeightSpace = AttrUtils.getDimensionFromAttr(attrs, DATEPICKER_ITEMHEIGHTSPACE,
                Utils.dp2px(context, WheelItemHeightSpace));
        boolean isZoomInSelectedItem = AttrUtils.getBooleanFromAttr(attrs, DATEPICKER_ZOOMINSELECTEDITEM, true);
        boolean isShowCurtain = AttrUtils.getBooleanFromAttr(attrs, DATEPICKER_WHEELCURTAIN, true);
        int curtainColor = AttrUtils.getColorFromAttr(attrs, DATEPICKER_WHEELCURTAINCOLOR, Color.WHITE.getValue());
        boolean isShowCurtainBorder = AttrUtils.getBooleanFromAttr(attrs, DATEPICKER_WHEELCURTAINBORDER, true);
        int curtainBorderColor = AttrUtils.getColorFromAttr(attrs, DATEPICKER_WHEELCURTAINBORDERCOLOR,
                com_ycuwq_datepicker_divider);

        setTextSize(textSize);
        setTextColor(textColor);
        setTextGradual(isTextGradual);
        setCyclic(isCyclic);
        setHalfVisibleItemCount(halfVisibleItemCount);
        setSelectedItemTextColor(selectedItemTextColor);
        setSelectedItemTextSize(selectedItemTextSize);
        setItemWidthSpace(itemWidthSpace);
        setItemHeightSpace(itemHeightSpace);
        setZoomInSelectedItem(isZoomInSelectedItem);
        setShowCurtain(isShowCurtain);
        setCurtainColor(curtainColor);
        setShowCurtainBorder(isShowCurtainBorder);
        setCurtainBorderColor(curtainBorderColor);
    }

    /**
     * Init child
     */
    private void initChild() {
        mYearPicker = (YearPicker) findComponentById(ResourceTable.Id_yearPicker_layout_date);
        mYearPicker.setOnYearSelectedListener(this);
        mMonthPicker = (MonthPicker) findComponentById(ResourceTable.Id_monthPicker_layout_date);
        mMonthPicker.setOnMonthSelectedListener(this);
        mDayPicker = (DayPicker) findComponentById(ResourceTable.Id_dayPicker_layout_date);
        mDayPicker.setOnDaySelectedListener(this);
    }

    /**
     * Set background *
     *
     * @param element element
     */
    @Override
    public void setBackground(Element element) {
        super.setBackground(element);
        if (mYearPicker != null && mMonthPicker != null && mDayPicker != null) {
            mYearPicker.setBackground(element);
            mMonthPicker.setBackground(element);
            mDayPicker.setBackground(element);
        }
    }


    /**
     * On date selected
     */
    private void onDateSelected() {
        if (mOnDateSelectedListener != null) {
            mOnDateSelectedListener.onDateSelected(getYear(),
                    getMonth(), getDay());
        }
    }


    /**
     * On month selected *
     *
     * @param month month
     */
    @Override
    public void onMonthSelected(int month) {
        mDayPicker.setMonth(getYear(), month);
        onDateSelected();
    }

    /**
     * On day selected *
     *
     * @param day day
     */
    @Override
    public void onDaySelected(int day) {
        onDateSelected();
    }


    /**
     * On year selected *
     *
     * @param year year
     */
    @Override
    public void onYearSelected(int year) {
        mMonthPicker.setYear(year);
        int month = getMonth();
        mDayPicker.setMonth(year, month);
        onDateSelected();
    }

    /**
     * Sets date.
     *
     * @param year  the year
     * @param month the month
     * @param day   the day
     */
    public void setDate(int year, int month, int day) {
        setDate(year, month, day, true);
    }

    /**
     * Sets date.
     *
     * @param year         the year
     * @param month        the month
     * @param day          the day
     * @param smoothScroll the smooth scroll
     */
    public void setDate(int year, int month, int day, boolean smoothScroll) {
        mYearPicker.setSelectedYear(year, smoothScroll);
        mMonthPicker.setSelectedMonth(month, smoothScroll);
        mDayPicker.setSelectedDay(day, smoothScroll);
    }

    /**
     * Set max date *
     *
     * @param date date
     */
    public void setMaxDate(long date) {
        setCyclic(false);
        mMaxDate = date;
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(date);
        mYearPicker.setEndYear(calendar.get(Calendar.YEAR));
        mMonthPicker.setMaxDate(date);
        mDayPicker.setMaxDate(date);
        mMonthPicker.setYear(mYearPicker.getSelectedYear());
        mDayPicker.setMonth(mYearPicker.getSelectedYear(), mMonthPicker.getSelectedMonth());
    }

    /**
     * Set min date *
     *
     * @param date date
     */
    public void setMinDate(long date) {
        setCyclic(false);
        mMinDate = date;
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(date);
        mYearPicker.setStartYear(calendar.get(Calendar.YEAR));
        mMonthPicker.setMinDate(date);
        mDayPicker.setMinDate(date);
        mMonthPicker.setYear(mYearPicker.getSelectedYear());
        mDayPicker.setMonth(mYearPicker.getSelectedYear(), mMonthPicker.getSelectedMonth());
    }

    /**
     * Gets date.
     *
     * @return the date
     */
    public String getDate() {
        DateFormat format = SimpleDateFormat.getDateInstance();
        return getDate(format);
    }

    /**
     * Gets date.
     *
     * @param dateFormat the date format
     * @return the date
     */
    public String getDate(DateFormat dateFormat) {
        int year;
        int month;
        int day;
        year = getYear();
        month = getMonth();
        day = getDay();
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month - 1, day);

        return dateFormat.format(calendar.getTime());
    }

    /**
     * Gets year.
     *
     * @return the year
     */
    public int getYear() {
        return mYearPicker.getSelectedYear();
    }

    /**
     * Gets month.
     *
     * @return the month
     */
    public int getMonth() {
        return mMonthPicker.getSelectedMonth();
    }

    /**
     * Gets day.
     *
     * @return the day
     */
    public int getDay() {
        return mDayPicker.getSelectedDay();
    }

    /**
     * Gets year picker.
     *
     * @return the year picker
     */
    public YearPicker getYearPicker() {
        return mYearPicker;
    }

    /**
     * Gets month picker.
     *
     * @return the month picker
     */
    public MonthPicker getMonthPicker() {
        return mMonthPicker;
    }

    /**
     * Gets day picker.
     *
     * @return the day picker
     */
    public DayPicker getDayPicker() {
        return mDayPicker;
    }

    /**
     * 一般列表的文本颜色
     *
     * @param textColor 文本颜色
     */
    public void setTextColor(int textColor) {
        mDayPicker.setTextColor(textColor);
        mMonthPicker.setTextColor(textColor);
        mYearPicker.setTextColor(textColor);
    }

    /**
     * 一般列表的文本大小
     *
     * @param textSize 文字大小
     */
    public void setTextSize(int textSize) {
        mDayPicker.setTextSize(textSize);
        mMonthPicker.setTextSize(textSize);
        mYearPicker.setTextSize(textSize);
    }

    /**
     * 设置被选中时候的文本颜色
     *
     * @param selectedItemTextColor 文本颜色
     */
    public void setSelectedItemTextColor(int selectedItemTextColor) {
        mDayPicker.setSelectedItemTextColor(selectedItemTextColor);
        mMonthPicker.setSelectedItemTextColor(selectedItemTextColor);
        mYearPicker.setSelectedItemTextColor(selectedItemTextColor);
    }

    /**
     * 设置被选中时候的文本大小
     *
     * @param selectedItemTextSize 文字大小
     */
    public void setSelectedItemTextSize(int selectedItemTextSize) {
        mDayPicker.setSelectedItemTextSize(selectedItemTextSize);
        mMonthPicker.setSelectedItemTextSize(selectedItemTextSize);
        mYearPicker.setSelectedItemTextSize(selectedItemTextSize);
    }


    /**
     * 设置显示数据量的个数的一半。
     * 为保证总显示个数为奇数,这里将总数拆分，itemCount = mHalfVisibleItemCount * 2 + 1
     *
     * @param halfVisibleItemCount 总数量的一半
     */
    public void setHalfVisibleItemCount(int halfVisibleItemCount) {
        mDayPicker.setHalfVisibleItemCount(halfVisibleItemCount);
        mMonthPicker.setHalfVisibleItemCount(halfVisibleItemCount);
        mYearPicker.setHalfVisibleItemCount(halfVisibleItemCount);
    }

    /**
     * Sets item width space.
     *
     * @param itemWidthSpace the item width space
     */
    public void setItemWidthSpace(int itemWidthSpace) {
        mDayPicker.setItemWidthSpace(itemWidthSpace);
        mMonthPicker.setItemWidthSpace(itemWidthSpace);
        mYearPicker.setItemWidthSpace(itemWidthSpace);
    }

    /**
     * 设置两个Item之间的间隔
     *
     * @param itemHeightSpace 间隔值
     */
    public void setItemHeightSpace(int itemHeightSpace) {
        mDayPicker.setItemHeightSpace(itemHeightSpace);
        mMonthPicker.setItemHeightSpace(itemHeightSpace);
        mYearPicker.setItemHeightSpace(itemHeightSpace);
    }


    /**
     * Set zoom in center item.
     *
     * @param zoomInSelectedItem the zoom in center item
     */
    public void setZoomInSelectedItem(boolean zoomInSelectedItem) {
        mDayPicker.setZoomInSelectedItem(zoomInSelectedItem);
        mMonthPicker.setZoomInSelectedItem(zoomInSelectedItem);
        mYearPicker.setZoomInSelectedItem(zoomInSelectedItem);
    }

    /**
     * 设置是否循环滚动。
     * set wheel cyclic
     *
     * @param cyclic 上下边界是否相邻
     */
    public void setCyclic(boolean cyclic) {
        mDayPicker.setCyclic(cyclic);
        mMonthPicker.setCyclic(cyclic);
        mYearPicker.setCyclic(cyclic);
    }

    /**
     * 设置文字渐变，离中心越远越淡。
     * Set the text color gradient
     *
     * @param textGradual 是否渐变
     */
    public void setTextGradual(boolean textGradual) {
        mDayPicker.setTextGradual(textGradual);
        mMonthPicker.setTextGradual(textGradual);
        mYearPicker.setTextGradual(textGradual);
    }


    /**
     * 设置中心Item是否有幕布遮盖
     * set the center item curtain cover
     *
     * @param showCurtain 是否有幕布
     */
    public void setShowCurtain(boolean showCurtain) {
        mDayPicker.setShowCurtain(showCurtain);
        mMonthPicker.setShowCurtain(showCurtain);
        mYearPicker.setShowCurtain(showCurtain);
    }

    /**
     * 设置幕布颜色
     * set curtain color
     *
     * @param curtainColor 幕布颜色
     */
    public void setCurtainColor(int curtainColor) {
        mDayPicker.setCurtainColor(curtainColor);
        mMonthPicker.setCurtainColor(curtainColor);
        mYearPicker.setCurtainColor(curtainColor);
    }

    /**
     * 设置幕布是否显示边框
     * set curtain border
     *
     * @param showCurtainBorder 是否有幕布边框
     */
    public void setShowCurtainBorder(boolean showCurtainBorder) {
        mDayPicker.setShowCurtainBorder(showCurtainBorder);
        mMonthPicker.setShowCurtainBorder(showCurtainBorder);
        mYearPicker.setShowCurtainBorder(showCurtainBorder);
    }

    /**
     * 幕布边框的颜色
     * curtain border color
     *
     * @param curtainBorderColor 幕布边框颜色
     */
    public void setCurtainBorderColor(int curtainBorderColor) {
        mDayPicker.setCurtainBorderColor(curtainBorderColor);
        mMonthPicker.setCurtainBorderColor(curtainBorderColor);
        mYearPicker.setCurtainBorderColor(curtainBorderColor);
    }

    /**
     * 设置选择器的指示器文本
     * set indicator text
     *
     * @param yearText  年指示器文本
     * @param monthText 月指示器文本
     * @param dayText   日指示器文本
     */
    public void setIndicatorText(String yearText, String monthText, String dayText) {
        mYearPicker.setIndicatorText(yearText);
        mMonthPicker.setIndicatorText(monthText);
        mDayPicker.setIndicatorText(dayText);
    }

    /**
     * 设置指示器文字的颜色
     * set indicator text color
     *
     * @param textColor 文本颜色
     */
    public void setIndicatorTextColor(int textColor) {
        mYearPicker.setIndicatorTextColor(textColor);
        mMonthPicker.setIndicatorTextColor(textColor);
        mDayPicker.setIndicatorTextColor(textColor);
    }

    /**
     * 设置指示器文字的大小
     * indicator text size
     *
     * @param textSize 文本大小
     */
    public void setIndicatorTextSize(int textSize) {
        mYearPicker.setTextSize(textSize);
        mMonthPicker.setTextSize(textSize);
        mDayPicker.setTextSize(textSize);
    }

    /**
     * Sets on date selected listener.
     *
     * @param onDateSelectedListener the on date selected listener
     */
    public void setOnDateSelectedListener(OnDateSelectedListener onDateSelectedListener) {
        mOnDateSelectedListener = onDateSelectedListener;
    }

    /**
     * The interface On date selected listener.
     */
    public interface OnDateSelectedListener {
        /**
         * On date selected.
         *
         * @param year  the year
         * @param month the month
         * @param day   the day
         */
        void onDateSelected(int year, int month, int day);
    }
}
